5.01. Справочник по TypeScript
Справочник по TypeScript
1. Основы типизации
Примитивные типы
TypeScript поддерживает следующие примитивные типы:
string— строка текстаnumber— числовое значение (включая целые и дробные)boolean— логическое значение (trueилиfalse)bigint— целое число произвольной длиныsymbol— уникальный и неизменяемый идентификаторundefined— значение, присваиваемое переменной, которая объявлена, но не инициализированаnull— явное отсутствие значения
Специальные типы
any— отключает проверку типов; переменная может принимать любое значениеunknown— безопасная альтернативаany; требует проверки перед использованиемnever— тип, представляющий значения, которые никогда не возникают (например, функция, выбрасывающая ошибку или зацикливающаяся)void— тип, указывающий отсутствие возвращаемого значения у функции
Тип object
Тип object описывает любой непримитивный тип. Он не включает null.
let obj: object = { a: 1 };
obj = [1, 2, 3];
obj = () => {};
Этот тип редко используется напрямую. Предпочтение отдается более точным описаниям структуры.
2. Составные типы
Объектные типы
Объектный тип описывает форму объекта через перечисление свойств и их типов:
type User = {
id: number;
name: string;
isActive: boolean;
};
Свойства могут быть опциональными:
type Config = {
theme?: 'light' | 'dark';
timeout?: number;
};
Свойства могут быть только для чтения:
type Point = {
readonly x: number;
readonly y: number;
};
Массивы
Массивы описываются двумя способами:
- Синтаксис
T[]:let numbers: number[] = [1, 2, 3]; - Синтаксис
Array<T>:let strings: Array<string> = ['a', 'b'];
Кортежи (Tuples)
Кортеж — массив фиксированной длины с известными типами элементов:
let rgb: [number, number, number] = [255, 128, 0];
Кортежи могут содержать опциональные элементы и остаточные параметры:
type HTTPResponse = [number, string?, ...string[]];
3. Объединения и пересечения
Объединение типов (|)
Объединение позволяет значению соответствовать одному из нескольких типов:
type ID = string | number;
type Status = 'loading' | 'success' | 'error';
Пересечение типов (&)
Пересечение объединяет несколько типов в один:
type A = { a: string };
type B = { b: number };
type C = A & B; // { a: string; b: number }
4. Функции
Типизация параметров и возврата
function greet(name: string): string {
return `Hello, ${name}`;
}
Функция может не возвращать значение:
function log(message: string): void {
console.log(message);
}
Необязательные и параметры по умолчанию
function createUser(name: string, age?: number) { /* ... */ }
function multiply(a: number, b: number = 1) { return a * b; }
Типы функций
Тип функции описывает сигнатуру:
type BinaryOperation = (x: number, y: number) => number;
const add: BinaryOperation = (a, b) => a + b;
Перегрузка функций
TypeScript поддерживает перегрузку функций через декларации:
function format(value: string): string;
function format(value: number): string;
function format(value: string | number): string {
return String(value);
}
5. Интерфейсы
Интерфейсы описывают контракты для объектов, классов и функций.
Базовый интерфейс
interface Person {
name: string;
age: number;
}
Расширение интерфейсов
interface Employee extends Person {
department: string;
}
Опциональные и readonly-свойства
interface Options {
timeout?: number;
readonly retries: number;
}
Индексные сигнатуры
interface Dictionary {
[key: string]: number;
}
Вызов и конструктор
interface Callable {
(input: string): boolean;
}
interface Constructable {
new (name: string): Instance;
}
6. Классы
Базовое объявление
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
move() { console.log(`${this.name} moves`); }
}
Модификаторы доступа
public— доступен везде (по умолчанию)private— доступен только внутри классаprotected— доступен внутри класса и его потомков
Параметры конструктора
class Point {
constructor(public x: number, public y: number) {}
}
Абстрактные классы
abstract class Shape {
abstract getArea(): number;
render() { /* общая логика */ }
}
Статические члены
class MathUtils {
static PI = 3.14159;
static double(x: number) { return x * 2; }
}
Реализация интерфейсов
class Bird implements Flyable {
fly() { /* ... */ }
}
7. Утилитарные типы
TypeScript предоставляет встроенные утилитарные типы для трансформации других типов.
Partial<T>
Делает все свойства типа T опциональными.
type PartialUser = Partial<User>; // { id?: number; name?: string; ... }
Required<T>
Делает все свойства обязательными.
Readonly<T>
Делает все свойства только для чтения.
Record<K, T>
Создает объектный тип с ключами типа K и значениями типа T.
type StatusCodeMap = Record<number, string>;
Pick<T, K>
Выбирает подмножество свойств из T по ключам K.
type NameOnly = Pick<User, 'name'>;
Omit<T, K>
Исключает указанные свойства из типа.
type WithoutId = Omit<User, 'id'>;
Exclude<T, U>
Исключает из T все типы, совместимые с U.
type NonNullable = Exclude<string | null | undefined, null | undefined>;
Extract<T, U>
Извлекает из T только те типы, которые совместимы с U.
NonNullable<T>
Удаляет null и undefined из объединения.
ReturnType<T>
Извлекает тип возвращаемого значения функции.
type R = ReturnType<() => string>; // string
Parameters<T>
Получает кортеж типов параметров функции.
type P = Parameters<(a: number, b: string) => void>; // [number, string]
ConstructorParameters<T>
Получает типы параметров конструктора.
InstanceType<T>
Получает тип экземпляра класса.
ThisType<T>
Указывает контекст this в объектных литералах.
8. Расширенные возможности типов
Условные типы
type IsString<T> = T extends string ? true : false;
Распределительные условные типы
Автоматически применяются к каждому элементу объединения.
Инференс в условных типах
type ReturnType<T> = T extends (...args: any) => infer R ? R : never;
Mapped Types
Создание новых типов на основе существующих с преобразованием ключей или значений.
type Nullable<T> = { [P in keyof T]: T[P] | null };
Template Literal Types
Позволяют создавать строки на основе шаблонов:
type EventName = `${'click' | 'hover'}-${'button' | 'link'}`;
// 'click-button' | 'click-link' | 'hover-button' | 'hover-link'
Key Remapping
В mapped types можно переименовывать ключи:
type Getters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K]
};
9. Модули и пространства имен
Модули ES
TypeScript использует стандартные модули ES:
// math.ts
export const PI = 3.14159;
export function add(a: number, b: number) { return a + b; }
// main.ts
import { PI, add } from './math';
Пространства имен
namespace Utils {
export function log(msg: string) { console.log(msg); }
}
Пространства имен рекомендуются только для глобальных библиотек или legacy-кода.
10. Декларации
Глобальные декларации
declare var VERSION: string;
declare function initialize(): void;
Декларации модулей
declare module 'my-library' {
export function doSomething(): void;
}
Расширение существующих интерфейсов
interface Window {
myCustomProp: string;
}
11. Конфигурация TypeScript (tsconfig.json)
Полный список опций компилятора:
Основные настройки
target— версия ECMAScript (например,"ES2020","ES2022")module— система модулей ("commonjs","es2020","esnext")lib— библиотеки, включаемые в компиляцию (["DOM", "ES2022"])outDir— директория для скомпилированного JSrootDir— корневая директория исходниковdeclaration— генерировать.d.tsфайлыsourceMap— генерировать source maps
Проверка типов
strict— включает все строгие проверкиnoImplicitAny— запрещает неявныйanystrictNullChecks— требует явной обработкиnull/undefinedstrictFunctionTypes— усиливает проверку типов функцийstrictBindCallApply— строгая типизация методовbind,call,applystrictPropertyInitialization— требует инициализации всех свойств классаnoImplicitThis— запрещает неявныйthisтипаanyalwaysStrict— добавляет"use strict"в каждый файл
Модули и разрешение
moduleResolution— стратегия разрешения модулей ("node","classic")baseUrl— базовый URL для абсолютных импортовpaths— маппинг путейresolveJsonModule— разрешить импорт JSON-файловesModuleInterop— улучшает совместимость с CommonJS
JSX
jsx— режим обработки JSX ("preserve","react","react-jsx")jsxFactory— функция для создания элементов (по умолчаниюReact.createElement)jsxFragmentFactory— фабрика для фрагментов
Экспериментальные возможности
experimentalDecorators— поддержка декораторовemitDecoratorMetadata— генерация метаданных для декораторов
Отладка и производительность
incremental— инкрементальная сборкаtsBuildInfoFile— файл для хранения информации о сборкеcomposite— поддержка проектных ссылок
Запреты и предупреждения
noUnusedLocals— предупреждать о неиспользуемых локальных переменныхnoUnusedParameters— предупреждать о неиспользуемых параметрахnoImplicitReturns— требовать явныйreturnво всех веткахnoFallthroughCasesInSwitch— запрет провалов вswitchallowUnreachableCode— разрешить недостижимый кодexactOptionalPropertyTypes— различатьundefinedи отсутствие свойства
12. Декораторы
Декораторы — экспериментальная возможность, позволяющая добавлять метаданные и изменять поведение классов, методов, свойств и параметров.
Включение декораторов
В tsconfig.json требуется:
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
Типы декораторов
-
Классовые декораторы:
function sealed(constructor: Function) {
Object.seal(constructor);
Object.seal(constructor.prototype);
}
@sealed
class Greeter { /* ... */ } -
Метод-декораторы:
function readonly(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
descriptor.writable = false;
}
class Math {
@readonly
double(x: number) { return x * 2; }
} -
Свойства-декораторы:
function format(template: string) {
return function (target: any, propertyKey: string) {
// можно сохранить метаданные через Reflect
};
}
class User {
@format("Hello, %s")
name: string;
} -
Параметр-декораторы:
function logParameter(target: any, methodName: string, paramIndex: number) {
// логика регистрации параметра
}
class Greeter {
greet(@logParameter name: string) { /* ... */ }
}
Метаданные
С включённой опцией emitDecoratorMetadata, TypeScript генерирует типы параметров и возвращаемых значений как метаданные, доступные через Reflect.getMetadata.
13. Работа с DOM и окружением
Глобальные типы
TypeScript автоматически подключает типы для DOM, если в lib указано "DOM".
Пример:
const button = document.getElementById('submit') as HTMLButtonElement;
button.addEventListener('click', () => { /* ... */ });
Определение глобальных переменных
// global.d.ts
interface Window {
__APP_VERSION__: string;
}
Теперь window.__APP_VERSION__ доступен без ошибок.
Работа с событиями
document.addEventListener('keydown', (event: KeyboardEvent) => {
if (event.key === 'Enter') { /* ... */ }
});
14. Интеграция с фреймворками
React
- Используются файлы
.tsx - Компоненты типизируются через
React.FC<Props> - Хуки (
useState,useEffect) выводят типы автоматически - Пропсы описываются интерфейсами или типами
interface ButtonProps {
label: string;
onClick: () => void;
}
const Button: React.FC<ButtonProps> = ({ label, onClick }) => (
<button onClick={onClick}>{label}</button>
);
Vue.js
- Поддержка через
defineComponent - Пропсы описываются в
propsс указанием типа - Композиционный API использует
ref,computedс выводом типов
import { defineComponent, PropType } from 'vue';
export default defineComponent({
props: {
title: { type: String as PropType<string>, required: true }
},
setup(props) {
// props.title — string
}
});
Angular
- Полная поддержка TypeScript «из коробки»
- Декораторы
@Component,@Injectableиспользуют метаданные - Типизация шаблонов через строгую проверку
Node.js
- Устанавливается пакет
@types/node - Глобальные объекты:
process,global,Buffer - Модули CommonJS и ES совместимы при правильной настройке
import * as fs from 'fs';
fs.readFile('file.txt', 'utf8', (err, data) => { /* ... */ });
15. Распространённые паттерны
Защита от null/undefined (Defensive Programming)
function processUser(user: User | null) {
if (!user) return;
// user теперь User
}
Discriminated Unions
type Success = { status: 'success'; data: string };
type Failure = { status: 'error'; message: string };
type Result = Success | Failure;
function handle(result: Result) {
if (result.status === 'success') {
// result.data доступен
}
}
Type Guards
function isString(value: unknown): value is string {
return typeof value === 'string';
}
if (isString(input)) {
// input — string
}
Branding Types (Nominal Typing Emulation)
type UserID = string & { readonly brand: unique symbol };
const createUserID = (id: string): UserID => id as UserID;
Immutability
Использование Readonly<T>, readonly массивов и spread-операторов:
const newState = { ...state, count: state.count + 1 };
16. Лучшие практики
- Всегда включайте
strict: true - Избегайте
any; используйтеunknownпри работе с внешними данными - Предпочитайте
interfaceдля публичных API,type— для утилит и union-типов - Используйте утилитарные типы вместо ручного копирования структур
- Пишите тесты с учётом типов (Jest + ts-jest)
- Разделяйте бизнес-логику и типы от инфраструктурного кода
- Не используйте
asбез необходимости; предпочитайте проверки типов
17. Инструменты и CLI
Компилятор tsc
Основные команды:
tsc --init— создаётtsconfig.jsontsc --watch— отслеживает изменения и перекомпилируетtsc --noEmit— только проверка типов, без генерации JStsc file.ts— компиляция одного файла
ESLint + TypeScript
- Используется
@typescript-eslint/parser - Правила:
no-explicit-any,strict-boolean-expressions,prefer-readonly
Prettier
Форматирование кода с поддержкой TypeScript и JSX.
TypeScript Playground
Онлайн-редактор на typescriptlang.org/play
18. Расширение TypeScript
AST и трансформеры
TypeScript предоставляет API для анализа и модификации Abstract Syntax Tree.
Пример использования:
import * as ts from 'typescript';
const source = ts.createSourceFile('test.ts', 'const x = 1;', ts.ScriptTarget.Latest);
Это используется в:
- Кастомных линтерах
- Кодогенераторах
- Babel-плагинах с поддержкой TS
- Framework-specific компиляторах (например, Angular)
Language Service API
Позволяет создавать IDE-функции: автодополнение, навигацию, рефакторинг.